package com.topvision.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.topvision.common.response.SuccessResponse;
import com.topvision.common.security.UserInfo;
import com.topvision.common.security.UserInfoUtils;
import com.topvision.domain.ArRecPro;
import com.topvision.domain.ImgRec;
import com.topvision.domain.ImgRecGroup;
import com.topvision.dto.ImageRecDto;
import com.topvision.dto.ImgRecGroupDTO;
import com.topvision.service.ArRecProService;
import com.topvision.service.ImgRecGroupService;
import com.topvision.service.ImgRecService;
import com.topvision.utils.*;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.security.Principal;
import java.time.LocalDate;
import java.util.*;

@RestController
@RequestMapping("/imgRec")
@Api(value = "图像识别API", description = "图像识别相关接口")
@Slf4j
public class ImgRecController {

    @Autowired
    private ImgRecService imgRecService;

    @Autowired
    private ImgRecGroupService imgRecGroupService;

    @Autowired
    private ArRecProService arRecProService;

    @Autowired
    private UserInfoUtils userInfoUtils;

    @GetMapping("/createGroup/{title}")
    public ResponseEntity createGroup(@PathVariable String title) {
        ImgRecGroup imgRecGroup = new ImgRecGroup();
        imgRecGroup.setTitle(title);
        imgRecGroupService.save(imgRecGroup);
        return ResponseEntity.ok(SuccessResponse.of(imgRecGroup));
    }

    @GetMapping("/imgRecGroups")
    public ResponseEntity imgRecGroups(Principal principal) {
        UserInfo userInfo = userInfoUtils.getUserInfo(principal);
        List<ImgRecGroup> groups = imgRecGroupService.findByCreatedBy(userInfo.getName());
        Set<String> groupIds = new HashSet<>();
        Map<String, ImgRecGroupDTO> imgRecGroupMap = new HashMap<>();
        groups.forEach(imgRecGroup -> {
            ImgRecGroupDTO imgRecGroupDTO = new ImgRecGroupDTO();
            BeanUtils.copyProperties(imgRecGroup, imgRecGroupDTO);
            imgRecGroupMap.put(imgRecGroup.getId().toString(), imgRecGroupDTO);
            groupIds.add(imgRecGroup.getId().toString());
        });
        List<ImgRec> imgRecs = imgRecService.findByGroupIdIn(groupIds);
        imgRecs.forEach(imgRec -> {
            if (imgRec.getGroupId() != null) {
                imgRecGroupMap.get(imgRec.getGroupId()).getImgRecs().add(imgRec);
            }
        });
        return ResponseEntity.ok(SuccessResponse.of(imgRecGroupMap));
    }

    @PostMapping("/addImage")
    public ResponseEntity addImage(HttpServletRequest request) {
        MultipartResolver resolver = new CommonsMultipartResolver(request.getSession().getServletContext());
        InputStream inputStream = null;
        InputStream ftpInputStream = null;
        ImgRec imgRec = new ImgRec();
        // 文件类型
        String type = null;
        String fileName = null;
        MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
        try {
            inputStream = multiRequest.getFile("file").getInputStream();
            fileName = multiRequest.getFile("file").getOriginalFilename();
            ftpInputStream = multiRequest.getFile("file").getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }

        type = fileName.indexOf(".") != -1 ? fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length()) : null;
        LocalDate today = LocalDate.now();
        String dir = today.toString().replace("-", "/");
        String filename = String.valueOf(System.currentTimeMillis());
        String name = type != null ? filename + "." + type : filename + ".jpg";

        //请求图像识别添加图片接口
        Map<String, Object> map = new LinkedHashMap<>();
        File tmpFile = null;
        String tmpname = FilenameUtils.getExtension(fileName);
        //手动创建临时文件
        tmpFile = new File(System.getProperty("java.io.tmpdir") + System.getProperty("file.separator") + dir + "/" + fileName);
        try {
            FileUtils.copyInputStreamToFile(inputStream, tmpFile);
        } catch (IOException e) {
            e.printStackTrace();
        }


        map.put("groupId", "4");
        map.put("data", tmpFile);
        JSONObject jsonObject = ArApiUtil.addImg(map);
        String jsonstr = jsonObject.toJSONString();

        String resultCode = jsonObject.get("result_code").toString();
        if (Integer.valueOf(resultCode) == 0) {


            if (StringUtils.isNotBlank(request.getParameter("groupId"))) {
                //  imgRec.setGroupId(request.getParameter("groupId"));
                imgRec.setSysGroupId(Long.valueOf(request.getParameter("groupId")));
            }
            if (StringUtils.isNotBlank(request.getParameter("title"))) {
                imgRec.setTitle(request.getParameter("title"));
            }
            if (StringUtils.isNotBlank(request.getParameter("imgDesc"))) {
                imgRec.setImgDesc(request.getParameter("imgDesc"));
            }
            if (StringUtils.isNotBlank(request.getParameter("videoUrl"))) {
                imgRec.setVideoUrl(request.getParameter("videoUrl"));
            }

            FtpConfigUtil.initFtp();
            try {
                FtpUtil.upload(ftpInputStream, name, Const.FTP_IMG_BASE_DIR + dir);
            } catch (Exception e) {
                e.printStackTrace();
            }
            String imgUrl = Const.FTP_IMG_BASE_URL + "imgRec/" + dir + "/" + name;
            imgRec.setImgUrl(imgUrl);

            JSONObject result = jsonObject.getJSONObject("result");
            JSONArray array = result.getJSONArray("success_img_list");
            JSONObject msg = array.getJSONObject(0);
            imgRec.setFileId(msg.getString("fileId"));
            imgRecService.save(imgRec);
            return ResponseEntity.ok(SuccessResponse.of(imgRec));
        } else {
            return ResponseEntity.ok(SuccessResponse.of("上传图像至图像识别服务器失败....."));
        }


        // return ResponseEntity.ok(SuccessResponse.of());
    }

    @PostMapping("/delImage/{id}")
    public ResponseEntity delImage(@PathVariable String id) {
        ImgRec imgRec = imgRecService.findOne(Long.valueOf(id));
        FtpConfigUtil.initFtp();
        String url = imgRec.getImgUrl();
        String[] strings = url.split("/");
        try {
            FtpUtil.delete(Const.FTP_IMG_BASE_DIR, strings[0]);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResponseEntity.ok(SuccessResponse.of());
    }


    @GetMapping("/groupImgRecs/{groupId}")
    public ResponseEntity imgRecs(@PathVariable String groupId) {
        List<ImgRec> imgRecs = imgRecService.findBySysGroupId(groupId);
        return ResponseEntity.ok(SuccessResponse.of(imgRecs));
    }


    @PostMapping("/imgPro")
    public ResponseEntity facePro(@RequestBody ArRecPro arRecPro) {
        if (arRecPro.getArRecId() != null) {
            arRecProService.save(arRecPro);
        }
        return ResponseEntity.ok(SuccessResponse.of(arRecPro));
    }

    @PostMapping("/recImage")
    public ResponseEntity recImg(HttpServletRequest request, Principal principal) {
        UserInfo userInfo = userInfoUtils.getUserInfo(principal);
        Map<String, Object> map = ArFileUtil.getFile(request, "file");
        Map<String, Object> parammap = new HashMap<>();
        parammap.put("Img", map.get("file"));
        JSONObject jsonObject = ArApiUtil.recImg(parammap);
        String resultCode = jsonObject.get("result_code").toString();
        if (resultCode != null && Integer.valueOf(resultCode) == 0) {
            if (jsonObject.get("result") != null) {
                JSONArray array = jsonObject.getJSONArray("result");
                if (array.size() > 0) {
                    JSONObject jsonObject1 = array.getJSONObject(0);
                    if (jsonObject1.get("matchLibs") != null) {
                        JSONArray matchLibs = jsonObject1.getJSONArray("matchLibs");
                        if (matchLibs.size() > 0) {
                            JSONObject object = matchLibs.getJSONObject(0);
                            if (object.get("matchFPs") != null) {
                                JSONArray matchFPs = object.getJSONArray("matchFPs");
                                if (matchFPs.size() > 0) {
                                    JSONObject result = matchFPs.getJSONObject(0);
                                    String fileId = result.getString("fpId");
                                    String score = result.getString("score");
                                    ImgRec imgRec = imgRecService.findByFileId(fileId);
                                    if (imgRec != null) {
                                        Long id = imgRec.getId();

                                        Map<String, Object> queryRecProMap = new HashMap<>();
                                        queryRecProMap.put("arRecId", id);
                                        queryRecProMap.put("createdBy", userInfo.getName());

                                        List<ArRecPro> arRecPros = arRecProService.list(queryRecProMap);
                                        ImageRecDto imageRecDto = new ImageRecDto();
                                        imageRecDto.setArRecPros(arRecPros);
                                        imageRecDto.setFileId(fileId);
                                        imageRecDto.setTitle(imgRec.getTitle());
                                        imageRecDto.setImgDesc(imgRec.getImgDesc());
                                        imageRecDto.setImgUrl(imgRec.getImgUrl());
                                        imageRecDto.setVideoUrl(imageRecDto.getVideoUrl());
                                        imageRecDto.setScore(score);

                                        return ResponseEntity.ok(SuccessResponse.of(imageRecDto));
                                    }
                                }
                            }
                        }
                    }

                }
            }

        }
        return ResponseEntity.ok(SuccessResponse.of());
    }
}
